﻿using CrawlerFramework.ConfigEntity;
using CrawlerFramework.Models;
using CrawlerFramework.Repository;
using MediaBot.Library;
using RakutenProxy.ConfigEntity;
using System;
using System.Text.RegularExpressions;
using System.Xml;

namespace RakutenProxy.PageProcessor
{
    internal class RakutenProductCategoryPageProcessor : CrawlerFramework.PageProcessor.PageProcessor
    {
        public RakutenProductCategoryPageProcessor(LinkConfig linkConfig, Link link)
            : base(linkConfig, link)
        {
        }

        private static bool IsNormalCategoryCode(string categoryCode)
        {
            var regex = new Regex("[^-]+-\\d+");
            var match = regex.Match(categoryCode);
            return match.Success;
        }

        public override CrawlStatus Execute()
        {
            Logger.Info("Start with Url: " + Link.Url);

            if (!ShouldExecute())
                return CrawlStatus.Paused;

            var linkRepo = new LinkRepository();

            try
            {
                Link.BeginExecution();

                var xmlSerializer = new XmlSerializer<RakutenProductCategoryConfig>();
                var entityConfigPath = LinkConfig.BuildEntityConfigPath();
                var config = xmlSerializer.Deserialize(entityConfigPath);

                var namespaces = Utils.GetDefaultNamespaces();

                var xmlWebPage = new XmlWebPage(new Uri(Link.Url), namespaces);
                xmlWebPage.Download();

                var categoryNodes = xmlWebPage.SelectNodes(config.ProductCategoryNode.Context);
                var nsManager = xmlWebPage.XmlNamespaceManager;

                foreach (XmlNode categoryNode in categoryNodes)
                {
                    try
                    {
                        var categoryCode = config.ProductCategoryCode.GetString(categoryNode, nsManager);
                        var categoryUrl = config.ProductCategoryUrl.GetString(categoryNode, nsManager);

                        var link = new Link { Url = categoryUrl, RelatedEntityName = Link.RelatedEntityName, RelatedEntityId = Link.RelatedEntityId };

                        linkRepo.Add(link);
                    }
                    catch { }
                }

                linkRepo.Save();
            }
            catch (Exception e)
            {
                var methodInfo = System.Reflection.MethodBase.GetCurrentMethod();
                var message = Utils.BuildErrorMessage(methodInfo, LinkConfig.Guid, Link.LinkId);
                Logger.Error(message, e);
                Link.EndExecution(CrawlStatus.CompletedWithError);
                return CrawlStatus.CompletedWithError;
            }
            finally
            {
                linkRepo.Dispose();
                Logger.Info("Finish link: " + Link.Url);

                if (DoneEvent != null) DoneEvent.Set();
            }

            Link.EndExecution(CrawlStatus.Completed);
            return CrawlStatus.Completed;
        }
    }
}